#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <WindowsX.h>
#include <assert.h>
#include <conio.h>
#include "resource.h"
#include "Game.h"
//#include "Globals.h"		(Abstracted through Engine.hpp)
//#include "Zone.hpp"		(Abstracted through Engine.hpp)
//#include "Button.hpp"		(Abstracted through Engine.hpp)
//#include "MenuPanel.hpp"	(Abstracted through Engine.hpp)
//#include "Pathogen.h"		(Abstracted through Engine.hpp)

/*Variable Declarations*/
L_Zone		Z_List;		//List of Zones
L_Object	O_List;		//List Static UI objects.
L_Button	B_List;		//List of the UIButtons and Close Buttons
L_Menu		M_List;		//List of all menu panels

static float Frame = 100;

/*Functon Prototypes*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR psCmdLine, int nCmdShow);
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
HWND OpenWindow(const char* cszClassName, const char* cszWindowName, int nCmdShow);

void CreateStaticObjects()
{
	O_List.push_back(new Drawable(ScreenW/2,265,0.5f,0.5f,TYPE_MAP,TEX_MAP));
	O_List.push_back(new Drawable(ScreenW/2,30,1.00f,0.5f,TYPE_MAP,TEX_BAR));
	O_List.push_back(new Drawable(ScreenW/2,500,1.00f,0.5f,TYPE_MAP,TEX_BAR));

}
void CreateZoneObjects()
{
	Z_List.push_back(new Zone(ZONE_KAJHTAI,		1001,	473,218, 0.49f, 0.66f));		
	Z_List.push_back(new Zone(ZONE_KHATOUM,		2001,	436,150, 0.56f, 0.49f));		
	Z_List.push_back(new Zone(ZONE_AEMPIS,		3001,	700,167, 0.64f, 0.42f));		
	Z_List.push_back(new Zone(ZONE_FAURRIEAST,	4001,	634,86,  0.41f, 0.54f));		
	Z_List.push_back(new Zone(ZONE_FAURRIWEST,	5001,	454,94,  0.39f, 0.59f));		
	Z_List.push_back(new Zone(ZONE_VALDUTAN,	6001,	589,130, 0.37f, 0.80f));		
	Z_List.push_back(new Zone(ZONE_VERINWEST,	7001,	38 ,210, 0.45f, 0.5f));		
	Z_List.push_back(new Zone(ZONE_VERINEAST,	8001,	245,225, 0.43f, 0.43f));		
	Z_List.push_back(new Zone(ZONE_VERINCENTER,	9001,	115,245, 0.5f,  0.5f));		
	Z_List.push_back(new Zone(ZONE_NEGEWEST,	8001,	731,162, 0.5f,  0.56f));		
	Z_List.push_back(new Zone(ZONE_NEGEEAST,	7001,	865,186, 0.68f, 0.5f));		
	Z_List.push_back(new Zone(ZONE_MARIANIYAH,	6001,	532,365, 0.33f, 0.43f));		
	Z_List.push_back(new Zone(ZONE_SIASYA,		5001,	748,408, 0.61f, 0.56f));		
	Z_List.push_back(new Zone(ZONE_SANKT,		4001,	938,289, 0.55f, 0.76f));		
	Z_List.push_back(new Zone(ZONE_VALUSERRH,	2001,	565,240, 0.53f, 0.7f));		

}
void CreateMenuObjects()
{
#ifdef SHAME
	int i(ZONE_KAJHTAI);
	for each(Zone* pObj in Z_List)	
	{
		M_List.push_back(new MenuPanel(500,265, 1.00f, 0.75f,GS_mZONE,i,pObj->GetName()));
		i++;
	}
#endif
	M_List.push_back(new MenuPanel(ScreenW/2,265, 1.00f, 0.75f,GS_mWORLD	,-1,"World Menu"  ));
	M_List.push_back(new MenuPanel(ScreenW/2,265, 1.00f, 0.75f,GS_mOPTIONS	,-1,"Option Menu" ));	
	M_List.push_back(new MenuPanel(ScreenW/2,265, 1.25f, 0.75f,GS_mMUTATE	,-1,"Mutate Menu" ));
	M_List.push_back(new MenuPanel(ScreenW/2,616, 1.95f, 0.33f,GS_ALWAYS	,-2,"EventBox"	  ));

	Engine::Into()->InitializeMenuList(M_List);
}
void CreateButtonObjects()
{
#ifdef SHAME
	for each(Zone* pObj in Z_List)		//This goes here so that its at value aligns with Zone List's
	{
		float zX(pObj->m_vecPosition.x);		
		float zY(pObj->m_vecPosition.y);			
		B_List.push_back(new Button(zX,zY,0.1f,0.45f,GS_GAMEPLAY,GS_mZONE,"",B_ZONES));
	}
#endif
	B_List.push_back(new Button(100,500 ,1,1,GS_ALWAYS   ,GS_mWORLD   ,"World"		  ,B_ALWAYS));		
	B_List.push_back(new Button(250,500 ,1,1,GS_ALWAYS   ,GS_mOPTIONS ,"Options"	  ,B_ALWAYS));	
	B_List.push_back(new Button(400,500 ,1,1,GS_ALWAYS   ,GS_mMUTATE  ,"Mutate"		  ,B_ALWAYS));
	B_List.push_back(new Button(685,98	,1,1,GS_mOPTIONS ,GS_GAMEPLAY ,"Close Window" ,B_ALWAYS));	
	B_List.push_back(new Button(685,98	,1,1,GS_mMUTATE  ,GS_GAMEPLAY ,"Close Window" ,B_ALWAYS));	
	B_List.push_back(new Button(685,98	,1,1,GS_mWORLD   ,GS_GAMEPLAY ,"Close Window" ,B_ALWAYS));	
	B_List.push_back(new Button(685,98	,1,1,GS_mZONE    ,GS_GAMEPLAY ,"Close Window" ,B_ALWAYS));	

	for(int i(0),mX(250),mY(150);i < MaxManifests;i++)
	{
		string Name = Pathogen::Into()->m_AllManifests[i].m_sName;	
		B_List.push_back(new Button((float)mX,(float)mY,0.75f,1.0f,GS_mMUTATE,GS_mMUTATE,Name,B_PURCHASE));

		((i+1)%5==0?mX=250,mY+=50:mX+=120);							
	}
	Engine::Into()->InitializeButtonList(B_List);
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	HWND hWnd = OpenWindow("D3DWindow", " PATHOGEN ", nCmdShow);	//Create the window
	if (NULL == hWnd){return E_FAIL;}								//Unless of course you can't
	MSG uMsg;
	memset(&uMsg, 0, sizeof(uMsg));

	Engine::Into()->Initialize(hWnd,hInstance);
	CreateStaticObjects();
	CreateZoneObjects();
	CreateMenuObjects();
	CreateButtonObjects();


	while (uMsg.message != WM_QUIT)
	{
		Input::Into()->UpdateInput(hWnd);
		Engine::Into()->UpdateObjects(Z_List,O_List,B_List,M_List);
		Engine::Into()->Render(Z_List,O_List,B_List,M_List);
		while (PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE))
		{TranslateMessage(&uMsg);DispatchMessage(&uMsg);}
	}

	UnregisterClass("D3DWindow", hInstance);
	return uMsg.wParam;
}
HWND OpenWindow(const char* cszWinClassName, const char* cszWindowName, int nCmdShow)
{
	/* Register window class and create window */
	WNDCLASSEX winClass;
	HWND hWnd;
	HINSTANCE hInstance = ::GetModuleHandle(NULL);
	assert(NULL != hInstance);
	HICON hIcon = ::LoadIcon(hInstance, MAKEINTRESOURCE(IDI_ICON1));
	//assert(NULL != hIcon);

	winClass.lpszClassName = cszWinClassName;
	winClass.cbSize        = sizeof(WNDCLASSEX);
	winClass.style         = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc   = WindowProc;
	winClass.hInstance     = hInstance;
	winClass.hIcon	       = hIcon;
	winClass.hIconSm	   = hIcon;
	winClass.hCursor       = ::LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)::GetStockObject(BLACK_BRUSH);
	winClass.lpszMenuName  = NULL;
	winClass.cbClsExtra    = 0;
	winClass.cbWndExtra    = 0;

	if (0 == RegisterClassEx(&winClass))
	{return NULL;}

	hWnd = 
		::CreateWindowEx
		(NULL,
		cszWinClassName,
		cszWindowName,
		WS_OVERLAPPEDWINDOW,
		0, 0,
		ScreenW, ScreenH,
		NULL, NULL, 
		::GetModuleHandle(NULL), NULL);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return hWnd;
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_CLOSE:

		O_List.clear();
		Z_List.clear();
		B_List.clear();
		M_List.clear();

		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
